﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using NewFormatProject.Infrastructure.Atrributes;
using NewFormatProject.Infrastructure.Dto.Datas;
using NewFormatProject.Infrastructure.Dto.Requests;
using NewFormatProject.Infrastructure.Dto.Responses;
using NewFormatProject.Infrastructure.EFCore;
using NewFormatProject.Infrastructure.Tools;
using NewFormatProject.Server.EFCore;
using NewFormatProject.Server.Interfaces;
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;

namespace NewFormatProject.Server.Instances
{
    internal class LoginIOC
    {
        public SysUserServerEF sysUserServerEF { get; set; }
        public LoginLogServerEF loginLogServerEF { get; set; }
    }
    [InjectClass]
    public class LoginServer : ILoginServer
    {
        private readonly LoginIOC _loginIOC;
        private readonly IConfiguration _configuration;
        public LoginServer(DbContext dbContext, IConfiguration configuration)
        {
            _loginIOC = new LoginIOC
            {
                sysUserServerEF = new SysUserServerEF(dbContext),
                loginLogServerEF = new LoginLogServerEF(dbContext)
            };
            _configuration = configuration;
        }


        #region 获取日志
        public async Task<ResponseApiDto> GetLoginLog(int uid, int page, int limit)
        {
            int total = 0;
            List<LoginLogs> logs = await _loginIOC.loginLogServerEF.Pagination1(d => d.LlUserId == uid, false, d => d.LlCreateTime, out total, page, limit).ToListAsync();
            return ResponseApiDto.Success("数据已获取", new PaginationData { data = logs, total = total });
        }
        #endregion

        #region 获取最后登录的日志
        public LoginLogs GetLastLoginLog(int uid)
        {
            var LastLog = _loginIOC.loginLogServerEF.Query(d => d.LlUserId == uid, false, d => d.LlCreateTime).FirstOrDefault();
            return LastLog;
        }
        #endregion

        #region 管理员登录
        public async Task<ResponseApiDto> Login(RequestLoginDto dto)
        {
            var iqUser = _loginIOC.sysUserServerEF.Query(d => d.UAccount == dto.account);
            if (!await iqUser.AnyAsync())
            {
                return ResponseApiDto.Fail("账号或密码错误");
            }
            var user = await iqUser.SingleAsync();
            var encryptPassword = Encrypt.GetMd5Hash(dto.password + user.USalt);
            if (user.UPassword != encryptPassword)
            {
                return ResponseApiDto.Fail("账号或密码错误");
            }
            if (user.URole != "管理员")
            {
                return ResponseApiDto.Fail("只有管理员能登录");
            }
            var code = Tools.Guid_1();
            var addLoginLog=await AddLoginLog(new LoginLogs
            {
                LlCode = code,
                LlUserId = user.UId
            });
            var tokenHandler = new JwtSecurityTokenHandler();
            var key = Encoding.ASCII.GetBytes(_configuration["JWT:secret"]); // 请使用一个复杂的密钥
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new Claim[]
                {
                    new Claim(ClaimTypes.Name, dto.account),
                    new Claim("uid",user.UId.ToString()),
                    new Claim("code",code), // 登录码
                }),
                Expires = DateTime.UtcNow.AddHours(1),
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature),
                Issuer = _configuration["JWT:issuer"],
                Audience = _configuration["JWT:audience"]
            };
            var token = tokenHandler.CreateToken(tokenDescriptor);

            return ResponseApiDto.Success("登录成功", new ResponseLoginDto
            {
                token = tokenHandler.WriteToken(token)
            });
        }
        // 添加登录日志
        private Task<int> AddLoginLog(LoginLogs loginLog)
        {
            return _loginIOC.loginLogServerEF.Add(loginLog);
        }


        #endregion

        #region 重置所有用户的密码
        //public async void ReSetPassword()
        //{
        //    List<SysUsers> users = _loginIOC.sysUserServerEF.Query().ToList();
        //    foreach (var user in users)
        //    {
        //        user.UPassword = Encrypt.GetMd5Hash(_configuration["Encrypt:DefaultPassword"] + user.USalt);
        //    }
        //   await _loginIOC.sysUserServerEF.Save();
        //}
        #endregion

        #region 生成测试用户
        public async Task<ResponseApiDto> GenerateTestUsers()
        {
            List<string> Salts= new List<string>();
            for (int i = 0; i < 2; i++)
            {
                Salts.Add(Tools.Guid_1());
            }
            var add=await _loginIOC.sysUserServerEF.Add(new List<SysUsers> {
            new SysUsers{
                UName="张三",
                UAccount="zhangsan",
                USalt=Salts[0],
                UPassword=Encrypt.GetMd5Hash("123456" + Salts[0]),
                URole="管理员",
                UPhone="12345678901"
            },new SysUsers{
                UName="赵六",
                USalt=Salts[1],
                UAccount="zhaoliu",
                UPassword=Encrypt.GetMd5Hash("123456" + Salts[1]),
                URole="普通用户",
                UPhone="09876543210"
            }
            });
            return ResponseApiDto.Create(add);
        }
        #endregion
    }
}
